#pragma once
//============================================================================
// Copyright (C) 2013 Brett R. Jones
//
// Issued to public domain 2013
//
// brettjones1900@gmail.com
// http://www.p2panarchy.com
//============================================================================

#include <string>
#include <vector>

//! replace \ with / and % with ?
int				MakeStringSafeForSprintf( char * pStr, int iLen );

bool			WildMatchString( std::string & cs, std::string& csWildStr );

bool			GetLine( std::string cs, unsigned int n, std::string &r );
bool			IsHexDecString( std::string& cs );
int				CountChars( const char * pStr, char cCharToLookFor );
int				CountChars( std::string& csStr, char cCharToLookFor );

bool			RemoveNonAlphaNums( std::string& cs );
bool			RemoveDoubleSpaces( std::string &cs );
std::string		GetSubstring( std::string& csStr, int iStartIdx, int iEndIdx );
bool			GetWord( std::string& csStr, int n, std::string& csRetToken );
//! Returns a pointer to the first occurrence of strSearch in strMain, or NULL if strSearch does not appear in str
const char *	StrStrNoCase( const char * strMain, const char * strSearch );
//! find position of string p2 in p1.. return -1 if not found
int				StrStrNoCasePosition( const char * strMain, const char * strSearch );
//! format into std::string using printf style format
void			StdStringFormat(	std::string & csStr,	// std::string to return formated results in
									const char * pFormat,	// string with format chars etc		
									... );					// vars
//! format into std::string using printf style format
void			StdStringFormat(	std::wstring & csStr,	// std::string to return formated results in
									const wchar_t * pFormat,	// string with format chars etc		
									... );					// vars
//!	find position of the given char.. if not found return -1			
int				StdStringFind( std::string & csStr, char cFindChar );
//!	find position of the given char..case insensitive if not found return -1			
int				StdStringFindCaseInsensitive( std::string & csStr, char cFindChar );
//!	find position of the given string if not found return -1			
int				StdStringFind( std::string & csStr, const char * pSubStr );
//!	find position of the given string case insensitive if not found return -1			
int				StdStringFindCaseInsensitive( std::string & csStr, const char * pSubStr );
//!	find position of the given char by searching from end to first if not found return -1			
int				StdStringReverseFind( std::string & csStr, char cFindChar );
//! make standard string upper case
void			StdStringMakeUpper( std::string & csStr );
//! make standard string lower case
void			StdStringMakeLower( std::string & csStr );
std::string		StdStringRight( std::string& cs, unsigned int n );
std::string		StdStringLeft( std::string& cs, unsigned int n );
std::string		StdStringRightOf( std::string& cs, char chr );
std::string		StdStringRightOfLast( std::string cs, char chr );
std::string		StdStringLeftOf( std::string cs, char chr );
std::string		StdStringLeftOfLast( std::string& cs, char chr);

//bool			StoreStdString( FILE * pgFile, std::string &cs );
//bool			LoadStdString( FILE * pgFile, std::string &cs );
//! copy string into buffer.. if string is to long then truncate
void			SafeStringCopy(		std::string		&strSrc,		// string to copy from
									char *			pBuf,			// buffer to copy into
									unsigned int	uiMaxBufLen );	// max length of buffer	
//! copy string into buffer.. if string is to long then truncate
void			SafeStringCopy(		const char *	pSrcString,		// string to copy from
									char *			pBuf,			// buffer to copy into
									unsigned int	uiMaxBufLen );	// max length of buffer	

//!	trim all at first instance of char		
void			StdStringTrim( std::string & csStr, const char cTrim );
//!	return string at first instance of char		
const wchar_t *	wstrchr( const wchar_t * wStr, const wchar_t wChar );
//!	trim all at first instance of char		
void			StdStringTrim( std::wstring & csStr, const wchar_t cTrim );

//!	trim leading and trailing whitespace		
void			StdStringTrim( std::string & csStr );
//!	trim leading and trailing whitespace		
void			StdStringTrim( std::wstring & csStr );

bool			isWhiteSpace( char cChar );
bool			isWhiteSpace( wchar_t wChar );

//!	split string into tokens		
void			StdStringSplit( const std::string & csStr, const char cToken, std::vector<std::string>& aoRetTokens );
//!	split wide string into tokens		
void			StdStringSplit( const std::wstring & csStr, const wchar_t cToken, std::vector<std::wstring>& aoRetTokens );

// return true if prefix matched beginning characters of string
bool			StdStringBeginsWith( std::string & csStr, const char * pPrefix );
// return true if suffix matched end characters of string
bool			StdStringEndsWith( std::string & csStr, const char * pSuffix );
// fill string with integer value
const char *	StdStringFromInteger( std::string & strResult, int iValue );
int				StdStringToInteger( std::string& strValue );


//============================================================================--
//! same as strstr but case insensitive
char * stristr( const char * pString, const char * pPattern );

int wstrlen( const wchar_t * pString );
wchar_t * wstrstr( const wchar_t * pString, const wchar_t * pPattern );
//! same as strstr but case insensitive
wchar_t * wstristr( const wchar_t * pString, const wchar_t * pPattern );
void wstrcpy( wchar_t * pwDest, const wchar_t * pwSrc );

std::wstring AsciiToWide( const std::string& utf8string );
std::string WideToAscii( const std::wstring& utf16String );

